import org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.Status
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.transport.CredentialsProvider
import org.eclipse.jgit.transport.RefSpec
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider
import java.io.File
import java.io.IOException
import java.nio.file.Paths

data class GitCtx(val baseDir: String, val url: String, val username: String, val password: String)


class GitUtils constructor(ctx: GitCtx) {
    val gitCtx: GitCtx = ctx

    fun openRpo(): Git? {
        var git: Git? = null
        try {
            val repository = FileRepositoryBuilder()
                .setGitDir(Paths.get(gitCtx.baseDir, ".git").toFile())
                .build()
            git = Git(repository)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return git
    }

    /**
     * 项目不存在会初始化
     * */
    fun init_repo() {
        val gitExit = File(gitCtx.baseDir, ".git")
        if (!gitExit.exists()) {
            val provider = UsernamePasswordCredentialsProvider(gitCtx.username, gitCtx.password)
            Git.cloneRepository().setURI(gitCtx.url).setDirectory(File(gitCtx.baseDir)).setCredentialsProvider(provider)
                .call()
        }
    }

    @Throws(Exception::class)
    fun add(git: Git) {
        git.add().addFilepattern(".").call() //添加全部文件
    }

    @Throws(Exception::class)
    fun status(git: Git): Status {
        return git.status().call()
    }

    @Throws(Exception::class)
    fun commit(git: Git): Boolean {
        val provider: CredentialsProvider = UsernamePasswordCredentialsProvider(gitCtx.username, gitCtx.password) //生成身份信息
        //        git.fetch().setRemote("origin").setRefSpecs(new RefSpec("master")).setCredentialsProvider(provider).call();
        git.pull().setRemote("origin")
            .setRemoteBranchName("master")
            .setCredentialsProvider(provider).call()
        val status: Status = status(git)
        if (status.isClean) {
            println("无文件变动，不做修改")
            return false
        }
        add(git)
        val progos_commit = git.commit().setAll(true).setMessage("progos commit").call()
        println("文件提交 commit_id=$progos_commit")
        return true
    }

    @Throws(Exception::class)
    fun push(git: Git) {
        val provider: CredentialsProvider = UsernamePasswordCredentialsProvider(gitCtx.username, gitCtx.password) //生成身份信息
        git.push()
            .setRemote("origin") //设置推送的URL名称
            .setRefSpecs(RefSpec("master")) //设置需要推送的分支,如果远端没有则创建
            .setCredentialsProvider(provider) //身份验证
            .call()
    }

    @Throws(Exception::class)
    fun pull(git: Git) {
        val provider: CredentialsProvider = UsernamePasswordCredentialsProvider(gitCtx.username, gitCtx.password) //生成身份信息
        git.pull().setRemote("origin")
            .setRemoteBranchName("master").setCredentialsProvider(provider).call()
    }
}


fun initRepo(gitCtx: GitCtx) {
    val gutil = GitUtils(gitCtx)
    gutil.init_repo()
}

fun syncRepo(ctx: GitCtx) {
    val gutil = GitUtils(ctx)

    val git = gutil.openRpo()
    git?.let {
        val commit: Boolean = gutil.commit(it)
        if (commit) {
            gutil.push(it)
        }
        gutil.pull(it)
    }
}

fun doSyncRepo() {
    SYSTEM_CONFG.gitRepoCfg.forEach { (t, u) ->
        val gitbase = SYSTEM_CONFG.gitrepobase + File.separator + t + File.separator + "base"
        val ctx = GitCtx(gitbase, u[0].repo, u[0].username, u[0].password)
        syncRepo(ctx)
    }
}
